
package view;

import java.awt.Dimension;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JFrame;

import main.Log;
import model.Executable;
import model.GameClock;
import model.effect.FlowEffect;
import model.effect.TeleportEffect;
import model.entity.Avatar;
import model.entity.stats.Stat;
import model.entity.stats.StatSet;
import model.entity.stats.StatType;
import model.entity.stats.StatWithMax;
import model.handler.AreaEffectHandler;
import model.interactionhandler.InteractionContainer;
import model.map.AreaEffect;
import model.map.Direction;
import model.map.FogOfWar;
import model.map.GameMap;
import model.map.HexLocationProjection;
import model.map.Location;
import model.map.MovementType;
import model.map.World;
import controller.AvatarController;
import controller.CameraController;
import controller.InteractionController;

public class NathanielTests {
	
	public static void main(String args[]) {
		testGrid();
//		testGameClock();
//		testEquipmentOverlay();
	}
	
	public static void testEquipmentOverlay() {
		EquipmentOverlay eo = new EquipmentOverlay( new Dimension(800,600), null, 
				new Point(200,200), null);
		
		GameWindow gw = new GameWindow("NathanielTests");
		gw.addOverlay( "testMapOverlay", eo );
		gw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gw.setSize( 800, 600 );
		gw.addMouseListener( GameButtonRegistry.getInstance() );
		gw.setVisible(true);
	}
	
	public static void testGrid() {
		Avatar avatar = createDummyAvatar();
		World.getInstance().setPlayer(avatar);
		
		GameMap gm = new GameMap();
		World.getInstance().addMap( gm );
		World.getInstance().setCurrentMap( gm );
		gm.addEntity( avatar );
		FogOfWar fow = new FogOfWar( gm, avatar, new HexLocationProjection());
		
		World.getInstance().setPlayer( avatar );
		
		MapOverlay mo = new MapOverlay( new Dimension(800,600), gm, new Location(13,13) );
		InteractionOverlay io = new InteractionOverlay( new Dimension(800,600), InteractionContainer.getInstance() );
		loadTestImages();//loads images into ModelToImage classes
		
		GameWindow gw = new GameWindow("NathanielTests");
		gw.setSize( 800, 600 );
		gw.addOverlay( "testMapOverlay", mo );
		gw.addOverlay( "testInteractionoverlay", io);
		
		StatsOverlay sl = new StatsOverlay(gw.getSize(), avatar, new Point(20, 20), 30);
        gw.addOverlay(OverlayIds.STATS, sl);
		
		initializeRefresh( gw );
		
		CameraController cc = new CameraController( mo, gw );
		AvatarController ac = new AvatarController( avatar, gw, mo, InteractionContainer.getInstance());
		InteractionController ic = new InteractionController( io, gw, InteractionContainer.getInstance());
		
		gw.addMouseListener( GameButtonRegistry.getInstance() );
		
		gw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gw.setVisible(true);
		
		// adds area effects
		// flow
		AreaEffect fa = new AreaEffect("river_se", new FlowEffect("flow", Direction.SE, 2.00));
		AreaEffect fb = new AreaEffect("river_s", new FlowEffect("flow", Direction.S, 2.00));
		AreaEffect fc = new AreaEffect("river_se", new FlowEffect("flow", Direction.SE, 1.00));
		AreaEffect fd = new AreaEffect("river_ne", new FlowEffect("flow", Direction.NE, 2.00));
		AreaEffect fe = new AreaEffect("river_nw", new FlowEffect("flow", Direction.NW, 2.00));
		AreaEffect ff = new AreaEffect("river_nw", new FlowEffect("flow", Direction.NW, 1.00));
		gm.addAreaEffect(new Location(19,19), fa);
		gm.addAreaEffect(new Location(19,20), fb);
		gm.addAreaEffect(new Location(19,21), fc);
		gm.addAreaEffect(new Location(20,19), fd);
		gm.addAreaEffect(new Location(20,20), fe);
		gm.addAreaEffect(new Location(20,21), ff);
		// teleport
		AreaEffect fg = new AreaEffect("areaEffect", new TeleportEffect("tpeffect", new Location(25,25)));
		gm.addAreaEffect(new Location(23,21), fg);

		AreaEffectHandler.getInstance().start();
		World.getInstance().getCurrentMap().getFogOfWar().update();
	}
	
	public static Avatar createDummyAvatar() {
		ArrayList<MovementType> mt = new ArrayList<MovementType>();
		mt.add( MovementType.GRASS );
		StatSet stats = new StatSet();
		stats.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		stats.addStat(StatType.SIGHTRANGE, new Stat(5, StatType.SIGHTRANGE));
		stats.addStat(StatType.HP, new StatWithMax(2000, StatType.HP, 2000));
        stats.addStat(StatType.MP, new StatWithMax(2000, StatType.MP, 2000));
		Avatar avatar = new Avatar("entity", Direction.S, new Location(11,13), stats, mt , null, null, null, false);
		return avatar;
	}
	
	public static void initializeRefresh( final GameWindow gw ) {
		GameClock.getInstance().scheduleAtFixedRate( 1, new Executable() {
			@Override
			public void execute() {
				gw.repaint();
			}
		} );
	}
	
	public static void loadTestImages() {
		ModelToImage.addImage( "Unpassable", "./Data/imgs/grayTile.png" );
		ModelToImage.addImage( "Grass", "./Data/imgs/greenTile.png" );
		ModelToImage.addImage( "obstacle", "./Data/imgs/obstacle.png" );
		ModelToImage.addImage( "areaEffect", "./Data/imgs/areaEffect.png" );
		ModelToImage.addImage( "decal", "./Data/imgs/decal.png" );
		ModelToImage.addImage( "item", "./Data/imgs/item.png" );
		
		//add river
		Map<Direction, String> r0 = new HashMap<Direction, String>();
		ModelToImage.addImage("river_s", "./Data/imgs/river_s.png");
		ModelToImage.addImage("river_se", "./Data/imgs/river_se.png");
		ModelToImage.addImage("river_sw", "./Data/imgs/river_sw.png");
		ModelToImage.addImage("river_n", "./Data/imgs/river_n.png");
		ModelToImage.addImage("river_ne", "./Data/imgs/river_ne.png");
		ModelToImage.addImage("river_nw", "./Data/imgs/river_nw.png");

		//add entity
		Map<Direction, String> m0 = new HashMap<Direction, String>();
		m0.put(Direction.S, "./Data/imgs/avatar_s.png");
		m0.put(Direction.SE, "./Data/imgs/avatar_se.png");
		m0.put(Direction.SW, "./Data/imgs/avatar_sw.png");
		m0.put(Direction.N, "./Data/imgs/avatar_n.png");
		m0.put(Direction.NE, "./Data/imgs/avatar_ne.png");
		m0.put(Direction.NW, "./Data/imgs/avatar_nw.png");
		DirectionalModelToImage.addImage("entity", m0);
		//add vehicle
		Map<Direction, String> m1 = new HashMap<Direction, String>();
		m1.put(Direction.S, "./Data/imgs/vehicle_n.png");
		DirectionalModelToImage.addImage("vehicle", m1);
		//add projectile
		ModelToImage.addImage( "projectile", "./Data/imgs/projectile.png" );
		
		//add semitransparent tile
		ModelToImage.addImage( "semitransparentTile", "./Data/imgs/semitransparentHexagon.png" );

	}

	public static void testGameClock() {
		final GameClock c = GameClock.getInstance();
		Log.out( Log.VIEW, "Before first executable.");
		final Executable e = new Executable() {
			@Override
			public void execute() {
				Log.out( Log.VIEW, "In first executable.");
			}
		};
		Executable e2 = new Executable() {
			@Override
			public void execute() {
				Log.out( Log.VIEW, "In second executable: remove first executable.");
				c.remove( e );
			}
		};
		c.scheduleAtFixedRate(80, e);
		c.schedule(410, e2);
	}
}
